package com.cocotingo.snail.template.models;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.cocotingo.snail.template.TemplateSyntaxException;

public class LayoutNode extends Node {
	
	private final List<LayoutFactorNode> factors;
	
	public LayoutNode() {
		factors = new ArrayList<LayoutFactorNode>(4);
	}
	
	public final void addLayoutFactor(LayoutFactorNode factor) {
		this.addLayoutFactor(factor, factors.size());
	}
	
	public void addLayoutFactor(LayoutFactorNode factor, int index) {
		if (factor == null) throw new IllegalArgumentException("cannot add null as a child node");
		factors.add(index, factor);
	}
	
	public void removeLayoutFactor(LayoutFactorNode factor) {
		factors.remove(factor);
	}
	
	public Iterable<LayoutFactorNode> factors() {
		return new Iterable<LayoutFactorNode>() {
			@Override
			public Iterator<LayoutFactorNode> iterator() {
				return factors.iterator();
			}
		};
	}

	@Override
	public void validateNode() throws TemplateSyntaxException {
		if (factors.size() == 4) {
			if (horizentalFactorCount() != 2) throw new TemplateSyntaxException(this, "Illegal number of horizental LayoutFactorNode: " + horizentalFactorCount() + ".");
			if (verticalFactorCount() != 2) throw new TemplateSyntaxException(this, "Illegal number of vertical LayoutFactorNode: " + verticalFactorCount() + ".");
		} else if (factors.size() == 2) {
			if (horizentalFactorCount() != 2 && verticalFactorCount() != 2)
				throw new TemplateSyntaxException(this, "Illegal number of LayoutFactorNode.");
		} else {
			throw new TemplateSyntaxException(this, "Illegal number of LayoutFactorNode: " + factors.size() + ".");
		}
	}
	
	private int horizentalFactorCount() {
		int cnt = 0;
		for (LayoutFactorNode node : factors) {
			if (node.isHorizentalFactor()) cnt++;
		}
		return cnt;
	}
	
	private int verticalFactorCount() {
		int cnt = 0;
		for (LayoutFactorNode node : factors) {
			if (node.isVerticalFactor()) cnt++;
		}
		return cnt;
	}
	
	public LayoutFactorNode[] getHorizentalFactors() {
		ArrayList<LayoutFactorNode> rst = new ArrayList<LayoutFactorNode>(2);
		for (LayoutFactorNode node : factors) {
			if (node.isHorizentalFactor()) rst.add(node);
		}
		return rst.toArray(new LayoutFactorNode[rst.size()]);
	}
	
	public LayoutFactorNode[] getVerticalFactors() {
		ArrayList<LayoutFactorNode> rst = new ArrayList<LayoutFactorNode>(2);
		for (LayoutFactorNode node : factors) {
			if (node.isVerticalFactor()) rst.add(node);
		}
		return rst.toArray(new LayoutFactorNode[rst.size()]);
	}
	
	@Override
	public Iterable<Node> children() {
		return new Iterable<Node>() {
			@Override
			public Iterator<Node> iterator() {
				return new Iterator<Node>() {
					Iterator<LayoutFactorNode> it = factors.iterator();
					@Override
					public boolean hasNext() {
						return it.hasNext();
					}
					@Override
					public Node next() {
						return it.next();
					}
					@Override
					public void remove() {
						throw new UnsupportedOperationException();
					}
				};
			}
		};
	}

	@Override
	protected String getXMLNodeName() {
		return "Layout";
	}

	@Override
	protected String getXMLAttributes() {
		return null;
	}

}
